#ifndef __INFRA_QUEUE_H__
#define __INFRA_QUEUE_H__

#include <linux/types.h>

#include "infra_comm.h"

#ifdef __cplusplus
extern "C" {
#endif

typedef void *infra_queue_handle;

typedef int32_t(*pfn_infra_queue_gb_cb)(void *puserdata, void *pdata);
typedef int32_t(*pfn_infra_queue_nt_cb)(void *puserdata, void *pdata);
typedef void(*pfn_infra_queue_travel_cb)(void *puserdata, void *pdata);
typedef bool(*pfn_infra_queue_find_cb)(void *puserdata, void *pdata);

typedef struct _infra_queue_stat_info {
    uint32_t    in_count;       /* queue push */
    uint32_t    out_count;      /* queue pop */
    uint32_t    stash_count;    /* queue's _data_count */
} infra_queue_stat_info_t;

infra_queue_handle infra_queue_create(uint32_t depth, uint32_t max_size, bool is_block, const char *token);
int32_t infra_queue_destroy(infra_queue_handle handle);
int32_t infra_queue_cleanup(infra_queue_handle handle);

int32_t infra_queue_set_depth(infra_queue_handle handle, int32_t depth);
int32_t infra_queue_get_depth(infra_queue_handle handle, int32_t *depth);
int32_t infra_queue_register_giveback_callback(infra_queue_handle handle, pfn_infra_queue_gb_cb callback,
        void *puserdata);
int32_t infra_queue_unregister_giveback_callback(infra_queue_handle handle);
int32_t infra_queue_register_notify_callback(infra_queue_handle handle, pfn_infra_queue_nt_cb callback,
        void *puserdata);
int32_t infra_queue_unregister_notify_callback(infra_queue_handle handle);

int32_t infra_queue_push(infra_queue_handle handle, void *pdata);
void* infra_queue_pop(infra_queue_handle handle, int32_t time_out);

int32_t infra_queue_travel(infra_queue_handle handle, pfn_infra_queue_travel_cb callback, void *puserdata);
void *infra_queue_find(infra_queue_handle handle, pfn_infra_queue_find_cb callback, void *puserdata);
void *infra_queue_front(infra_queue_handle handle);
void *infra_queue_back(infra_queue_handle handle);

int32_t infra_queue_empty(infra_queue_handle handle);
int32_t infra_queue_size(infra_queue_handle handle);
int32_t infra_queue_get_stat(infra_queue_handle handle, infra_queue_stat_info_t *pstat_info);

#ifdef __cplusplus
}
#endif

#endif  /* __INFRA_QUEUE_H__ */